package org.essilab.analyzer.application;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.Arrays;
import org.essilab.analyzer.Configuration.Config;
import org.essilab.analyzer.analyzer.Term;
import org.essilab.analyzer.analyzer.db.Parser;

/**
 * This class is used to create the list of useless words. The list is created
 * from the terms stored in file. The list is stored in "useless_words.ini".
 *
 * @author Mohamed-Amine Chouchene, Ahcène Idinarere, Vincent Nock, Alain
 * Janin-Manificat
 */
public class ApplicationLoadUselessWords {

    ArrayList<String> uselessTypes;
    String[] uselessTypesStringArray = {
        "Adjectif numéral",
        "Article indéfini",
        "pronom indéfini",
        "pronom personnel",
        "préposition",
        "Conjonction de coordination",
        "article partitif",
        "part",
        "caractère",
        "lettre",
        "Adjectif possessif",
        "adjectif indéfini",
        "Adverbe interrogatif",
        "Adverbe relatif",
        "Pronom démonstratif",
        "prénom",
        "conjonction",
        "Préfixe",
        "Locution pronominale",
        "Locution conjonctive",
        "Suffixe",
        "Locution prépositive",
        "Pronom possessif",
        "Article défini",
        "Adjectif interrogatif",
        "Pronom interrogatif",
        "Postposition",
        "pronom",
        "Adjectif exclamatif",
        "Interfixe",
        "Pronom relatif",
        "infixe",
        "Forme d’article défini",
        "forme d'adjectif indéfini",
        "symbole"
    };

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {

        Config.setFile("config.ini");

        File f = new File("useless_words.ini");
        f.delete();

        ApplicationLoadUselessWords app = new ApplicationLoadUselessWords();
        app.parser();
    }

    public ApplicationLoadUselessWords() {

        uselessTypes = new ArrayList<>();
        uselessTypes.addAll(Arrays.asList(uselessTypesStringArray));
    }

    /**
     * Parse all the stored terms and extract ones that shall be stored as
     * useless words. DB.
     *
     * @throws IOException
     */
    private void parser() throws IOException {

        Parser parser = new Parser(false);
        String absoluteRoot = Config.get("savePath") + "terms/";

        Path uselessWordsFile = Paths.get("useless_words.ini");
        Files.createFile(uselessWordsFile);
        try (BufferedWriter bw = Files.newBufferedWriter(uselessWordsFile,
                                                         Charset.forName("UTF-8"),
                                                         new OpenOption[]{StandardOpenOption.WRITE})) {
            File f = new File(absoluteRoot);
            for (String el : f.list()) {
                File t = new File(absoluteRoot + el);
                if (t.isDirectory()) {
                    String[] lists = t.list();
                    for (String e : lists) {
                        File file = new File(absoluteRoot + el + "/" + e);
                        if (file.isFile()) {
                            Term term = parser.parser(file);
                            fillUselessWordsConfigFile(bw, term);
                        }
                    }
                }
            }

            bw.flush();
        }
    }

    /**
     * Write a useless term in the list if all his types are in the uselessTypes
     * list.
     *
     * @param bw BufferedWriter - writer for file "useless_words.ini"
     * @param term Term - the term that may be put in the list.
     * @throws IOException
     */
    private void fillUselessWordsConfigFile(BufferedWriter bw, Term term) throws IOException {

        if (term != null) {
            if (isUselessWord(term.getTypes())) {
                if (term.getTitle() != null) {
                    bw.write(term.getTitle());
                    bw.write("\n");
                } else {
                    System.out.println("Term : " + term.getTitle());
                }
            }
        }
    }

    /**
     * Tell whether or not a word is useless according to his types list. If all
     * types are in the uselessTypes list, the word is considered useless.
     *
     * @param list java.util.List<String> - the types list of a Term.
     * @return boolean - True if all types are in uselessTypes list, false
     * otherwise.
     */
    private boolean isUselessWord(java.util.List<String> list) {

        if (list.isEmpty()) {
            return false;
        }

        for (String type : list) {
            if (uselessTypes.contains(type)) {
                return true;
            }
        }
        return false;
    }
}
